package com.gack.netty.clientTest;

import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;

/**
 * 
* @ClassName: NettyClientChannelWatchDog 
* @Description: TODO(连接链路狗  检测链接断开 自动重连 >> 心跳超时 重连机制) 
* @author (ZhangXinYu)  
* @date 2018年8月30日 下午10:51:43 
* @version V1.0
 */
@Sharable
public class NettyClientChannelWatchDog extends ChannelInboundHandlerAdapter implements TimerTask{

	private final Bootstrap bootstrap;
	private final Timer timer;
	private final int port;
	private final String host;
	private volatile boolean reconnect = true;
	private int attempts;
	
	public NettyClientChannelWatchDog(Bootstrap bootstrap, Timer timer, int port, String host, boolean reconnect) {
		this.bootstrap = bootstrap;
		this.timer = timer;
		this.port = port;
		this.host = host;
		this.reconnect = reconnect;
	}
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("当前链路已经激活，重试链接次数重置为0");
		this.attempts = 0;
		ctx.fireChannelActive();
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("链接关闭");
		if(reconnect){
			System.out.println("链接关闭,将尝试重新链接");
			if(attempts < 12){
				attempts ++;
			}
			int timeout = 2 << attempts;
//			System.out.println("定时任务超时时间:"+timeout);
//			timer.newTimeout(this, timeout, TimeUnit.MILLISECONDS);
			Thread.sleep(timeout);
			run();
		}
		ctx.fireChannelInactive();
	}
	
	public void run() throws Exception{
//		bootstrap.handler(new NettyClientInitializer(bootstrap, timer, host, port));
		ChannelFuture future = bootstrap.connect(host,port).sync();
		future.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				boolean succeed = future.isSuccess();
				if (!succeed) {
                    System.out.println("重连失败");
                    future.channel().pipeline().fireChannelInactive();
                }else{
                    System.out.println("重连成功");
                }
				
			}
		});
	}

	@Override
	public void run(Timeout timeout) throws Exception {
//		bootstrap.handler(new NettyClientInitializer(bootstrap, timer, host, port));
		ChannelFuture future = bootstrap.connect(host,port).sync();
		future.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				boolean succeed = future.isSuccess();
				if (!succeed) {
                    System.out.println("重连失败");
                    future.channel().pipeline().fireChannelInactive();
                }else{
                    System.out.println("重连成功");
                }
				
			}
		});
	}

}
